﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WinServiceFileListener.Consts;
using WinServiceFileListener.Extensions;
using WinServiceFileListener.Helpers;

namespace WinServiceFileListener
{
    public partial class FileListener : ServiceBase
    {
        public FileListener()
        {
            InitializeComponent();
        }
        private FileSystemWatcher fsw = new FileSystemWatcher();
        public void StartService(string[] args)
        {
            Program.FileListenerIniReadWrite();
            OnStart(args);
        }
        protected override void OnStart(string[] args)
        {
            //Debugger.Launch();
            this.WriteLog($"服务启动成功");
            fsw.Path = IniConst.FileListenPath;
            fsw.Filter = "*.*"; // 监听所有文件
            // 监听 LastWrite 时间更改
            fsw.EnableRaisingEvents = true;// 开始监听
            fsw.IncludeSubdirectories = true;
            fsw.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName;
            fsw.Changed += Fsw_Changed;
            
        }

        private void Fsw_Changed(object sender, FileSystemEventArgs e)
        {
            string strContains = "";
            string fullPath = e.FullPath;
            string listPathKey = IniConst.FileListenPathKey;
            var fileNames = IniConst.FileName.Split(' ');
            try
            {
                var fileName = Path.GetFileName(fullPath);
                if (!Array.Exists(fileNames, f => f.Equals(fileName, StringComparison.OrdinalIgnoreCase)))
                {
                    //throw new CustomException($"文件名【{fullPath}】不在复制文件内【{IniConst.FileName}】");
                    Debug.WriteLine($"当前文件：{fileName}");
                    return;
                }
                if (!string.IsNullOrEmpty(listPathKey) && !fullPath.IsContains(ref strContains, listPathKey))
                {
                    //throw new CustomException($"对文件【{fullPath}】不生效，因为该文件不在范围内【{strContains}】");
                    return;
                }
                
                // 若文件更新，复制文件
                CopyFilesToNewFolder(e.FullPath);
            }
            catch (CustomException ex)
            {
                this.WriteLog($"{ex.Message}");
            }
            catch (Exception ex)
            {
                string msg = $"复制文件【{fullPath}】异常：";
                this.WriteLog($"{msg}{ex}");
            }
            
        }
        
        /// <summary>
        /// 复制文件
        /// </summary>
        /// <param name="filePath">文件全路径，如：E:\Company\广医附一（横琴）\GyfyHqKrGuide\Common\bin\x86\Debug\Common.dll</param>
        /// <param name="updatedFilePath"></param>
        private void CopyFilesToNewFolder(string filePath)
        {
            string fileName = Path.GetFileName(filePath);//Common.dll
            string destDirectory = "";
            if (string.IsNullOrWhiteSpace(IniConst.CustomSavePath))
            {
                //获取文件的上级目录：E:\Company\广医附一（横琴）\GyfyHqKrGuide\Common\bin\x86\
                var parentPath = FolderHelper.GetParentDirectory(filePath);
                string baseDirc = DateTime.Now.ToString("yyyy-MMdd HHmm");
                destDirectory = Path.Combine(parentPath, baseDirc); // E:\Company\广医附一（横琴）\GyfyHqKrGuide\Common\bin\x86\2024-1018 0012                          
                FolderHelper.CreateFolder(destDirectory);
                
            }
            else
            {
                FolderHelper.CreateFolder(IniConst.CustomSavePath);
                //自定义保存路径
                destDirectory = IniConst.CustomSavePath;
            }

            string destFileName = Path.Combine(destDirectory, fileName);//E:\Company\广医附一（横琴）\GyfyHqKrGuide\Common\bin\x86\2024-1018 0012\Common.dll

            #region 重试机制
            int retryCount = 5; // 最大重试次数
            int delay = 1000; // 重试间隔（单位：毫秒）
            for (int i = 0; i < retryCount; i++)
            {
                try
                {
                    // 复制文件到新文件夹
                    File.Copy(filePath, destFileName, true); // true 表示覆盖现有文件

                    this.WriteLog($"文件 {fileName} 已复制到 {destFileName}");
                    break; // 复制成功，退出重试循环
                }
                catch (IOException ex)
                {
                    // 如果捕获到 IOException，等待一段时间后重试
                    this.WriteLog($"正在重试 {i + 1}/{retryCount}：{ex.Message}");
                    System.Threading.Thread.Sleep(delay);
                }
                catch (CustomException ex)
                {
                    this.WriteLog($"复制文件时出错：{ex.Message}");
                    System.Threading.Thread.Sleep(delay);
                }
                catch (Exception ex)
                {
                    this.WriteLog($"{ex.Message}");
                }
            } 
            #endregion

        }

        public void StopService()
        {
            OnStop();
        }
        protected override void OnStop()
        {
            FswStop();
            this.WriteLog("服务停止成功");
        }

        /// <summary>
        /// 停止监听文件是否改动
        /// </summary>
        protected void FswStop()
        {
            if (fsw != null)
            {
                fsw.EnableRaisingEvents = false;
                fsw.Dispose();
            }
        }
    }
}
